class_name BattleReward
extends Control

enum Type {GOLD, NEW_CARD}

const REWARD_BUTTON = preload("uid://deumfa7b5gw2l")
const GOLD_ICON := preload("uid://dhmtctwb5ymhc")
const GOLD_TEXT := "%s gold"
const CARD_TEXT := "Add New Card"
const CARD_ICON := preload("uid://du7r7v1iaahuo")

@export var run_stats: RunStats
@export var character_stats: CharacterStats
@export var relic_handler: RelicHandler

@onready var rewards: VBoxContainer = %Rewards

var card_reward_total_weight := 0.0
var card_rarity_weights := {
	Card.Rarity.COMMON: 0.0,
	Card.Rarity.UNCOMMON: 0.0,
	Card.Rarity.RARE: 0.0
}

func _on_back_button_pressed() -> void:
	Events.do_battle_reward_exited()
	
func _on_gold_reward_taken(amount: int) -> void:
	if not run_stats:
		return
	run_stats.gold += amount
	

func add_gold_reward(amount: int) -> void:
	var new_reward : RewardButton = REWARD_BUTTON.instantiate()
	new_reward.reward_icon = GOLD_ICON
	new_reward.reward_text = GOLD_TEXT % amount
	new_reward.pressed.connect(_on_gold_reward_taken.bind(amount))
	rewards.add_child.call_deferred(new_reward)
	
func add_card_reward() -> void:
	var card_reward :RewardButton = AutoLoader.REWARD_BUTTON_SCENE.instantiate()
	card_reward.reward_icon = CARD_ICON
	card_reward.reward_text = CARD_TEXT
	card_reward.pressed.connect(_show_card_rewards)
	rewards.add_child.call_deferred(card_reward)


func add_relic_reward(relic: Relic) -> void:
	if not relic:
		return
	var relic_reward :RewardButton = AutoLoader.REWARD_BUTTON_SCENE.instantiate()
	relic_reward.reward_icon = relic.icon
	relic_reward.reward_text = relic.relic_name
	relic_reward.pressed.connect(_on_relic_reward_pressed.bind(relic))
	rewards.add_child.call_deferred(relic_reward)


func _on_relic_reward_pressed(relic: Relic) -> void:
	if not relic or not relic_handler:
		return
	relic_handler.add_relic(relic)


func _show_card_rewards() -> void:
	if not run_stats or not character_stats:
		return
	var card_rewards :CardRewards = AutoLoader.CARD_REWARDS_SCENE.instantiate()
	add_child(card_rewards)
	card_rewards.card_reward_selected.connect(_on_card_reward_taken)
	var card_reward_array: Array[Card] = []
	var available_cards: Array[Card] = character_stats.draftable_cards.duplicate_cards()
	for i in run_stats.card_rewards:
		_setup_card_chances()
		var roll := RNG.instance.randf_range(0.0, card_reward_total_weight)
		for rarity: Card.Rarity in card_rarity_weights:
			if card_rarity_weights[rarity] > roll:
				_modify_weights(rarity)
				var picked_card := _get_random_avaliable_card(available_cards, rarity)
				if not picked_card:
					continue
				card_reward_array.append(picked_card)
				available_cards.erase(picked_card)
				break
	card_rewards.rewards = card_reward_array
	card_rewards.show()
				
func _get_random_avaliable_card(available_cards: Array[Card], with_rarity: Card.Rarity) -> Card:
	var all_possible_cards := available_cards.filter(func(card:Card): return card.rarity == with_rarity)
	return RNG.pick_random(all_possible_cards)


func _modify_weights(rarity_rolled: Card.Rarity) -> void:
	if rarity_rolled == Card.Rarity.RARE:
		run_stats.rare_weight = RunStats.BASE_RARE_WEIGHT
	else:
		run_stats.rare_weight = clampf(run_stats.rare_weight + 0.3, run_stats.BASE_RARE_WEIGHT, 5.0)
	
	
func _setup_card_chances() -> void:
	card_reward_total_weight = run_stats.common_weight + run_stats.uncommon_weight + run_stats.rare_weight
	card_rarity_weights[Card.Rarity.COMMON] = run_stats.common_weight
	card_rarity_weights[Card.Rarity.UNCOMMON] = run_stats.common_weight + run_stats.uncommon_weight
	card_rarity_weights[Card.Rarity.RARE] = card_reward_total_weight
	
	
func _on_card_reward_taken(card: Card) -> void:
	if not character_stats or not card:
		return
	character_stats.deck.add_card(card)
